using System.Collections.Generic;

namespace OracleInternal.Common
{
	internal class SyncQueueList<T>
	{
		internal List<T> m_list;

		internal object m_sync;

		internal int m_max;

		internal bool m_bMaxExplicitlySet;

		internal T this[int index]
		{
			get
			{
				lock (m_sync)
				{
					return m_list[index];
				}
			}
		}

		internal int Count => m_list.Count;

		internal SyncQueueList(int max = int.MaxValue)
		{
			m_list = new List<T>();
			m_sync = new object();
			m_max = max;
			if (m_max != int.MaxValue)
			{
				m_bMaxExplicitlySet = true;
			}
		}

		internal List<T> GetList()
		{
			List<T> list = new List<T>();
			lock (m_sync)
			{
				for (int i = 0; i < m_list.Count; i++)
				{
					list.Add(m_list[i]);
				}
				return list;
			}
		}

		internal void Enqueue(T t)
		{
			if (!m_bMaxExplicitlySet || m_list.Count < m_max)
			{
				lock (m_sync)
				{
					m_list.Add(t);
				}
			}
		}

		internal void Enqueue(ref T t)
		{
			if (!m_bMaxExplicitlySet || m_list.Count < m_max)
			{
				lock (m_sync)
				{
					m_list.Add(t);
				}
			}
			t = default(T);
		}

		internal bool Dequeue(out T t)
		{
			lock (m_sync)
			{
				if (m_list.Count == 0)
				{
					t = default(T);
					return false;
				}
				t = m_list[0];
				m_list.Remove(t);
				return true;
			}
		}

		internal virtual T Dequeue()
		{
			lock (m_sync)
			{
				if (m_list.Count == 0)
				{
					return default(T);
				}
				T val = m_list[0];
				m_list.Remove(val);
				return val;
			}
		}

		internal void Add(T t)
		{
			lock (m_sync)
			{
				m_list.Add(t);
			}
		}

		internal bool AddIfNotExist(T t)
		{
			lock (m_sync)
			{
				if (!m_list.Contains(t))
				{
					m_list.Add(t);
					return true;
				}
			}
			return false;
		}

		internal bool Contains(T t)
		{
			lock (m_sync)
			{
				return m_list.Contains(t);
			}
		}

		internal int IndexOf(T t)
		{
			lock (m_sync)
			{
				return m_list.IndexOf(t);
			}
		}

		internal bool Remove(T t, int minRequirement)
		{
			if (m_list.Count > minRequirement)
			{
				lock (m_sync)
				{
					if (m_list.Count > minRequirement)
					{
						return m_list.Remove(t);
					}
					return false;
				}
			}
			return false;
		}

		internal bool Remove(T t)
		{
			lock (m_sync)
			{
				return m_list.Remove(t);
			}
		}

		internal void Clear()
		{
			lock (m_sync)
			{
				m_list.Clear();
			}
		}
	}
}
